--[[
邮件模块业务逻辑总入口
接口列表：
AddMailToUser 发邮件
--FetchMailAttachment 取附件
GetMailByID 根据mailID取一封邮件
GetMails 取一个人的所有邮件

邮件db里面包含字段
mailID			邮件id
receiverUuid	收件人Uuid
title			标题（用户邮件不存在）
content			邮件内容
sendTime		发送时间
isRead			是否已读（0-未，1-是）
gridList		附件(列表)
--]]

local LuaMongo = _G.lua_mongo
local DB = require("common.DB")
local MailDefine = require("mail.Define")
local RoleFFI = require("role.RoleFFI")
local Human   = require("core.Human")
local Msg = require("core.Msg")
local RoleDBLogic = require("role.RoleDBLogic")
--local Util = require("common.Util")
local InnerDataDefine = require("innerdata.Define")
local InnerDataManagerFW = require("innerdata.InnerDataManagerFW")
local Lang = require("common.Lang")
local Config = require("Config")
local MiddleLogic = require("middle.MiddleLogic")

local QueryUpdateTable = { _id = nil }
local QueryRemoveTable = { _id = nil }

mailID2Uid = mailID2Uid or {}
mailUid2ID = mailUid2ID or {}

function initAfterStart()

    -- 删除超过15天的邮件
    local mailList = {}
    local mailLen = 0
    LuaMongo.find(DB.db_mail, nil)
    while true do
        local tmp = {}
        if not LuaMongo.next(tmp) then
            break
        end
        mailLen = mailLen + 1
        mailList[mailLen] = tmp._id
    end


    local query = {}
    local del = {}
    local now = os.time()
    for i = 1, mailLen do
        query._id = mailList[i]
        LuaMongo.find(DB.db_mail)
        local data = {}
        if not LuaMongo.next(data) then
            assert()
        end

        if now - data.sendTime > 15 * 86400 then
            del._id = mailList[i]
            LuaMongo.remove(DB.db_mail, del)
        end
    end
end

local function initMailID()
    if mailID2Uid[0] == nil then
        local id = 0
        LuaMongo.find(DB.db_mail, nil)
        while true do
            local tmp = {}
            if not LuaMongo.next(tmp) then
                break
            end

            id = id + 1
            mailID2Uid[id] = tmp._id
            mailUid2ID[tmp._id] = id
        end
        mailID2Uid[0] = id
    end
end

function AddMailToUser(receiverUuid, content, gridList, title)
    local mail = {}
    mail.receiverUuid = receiverUuid
    mail.content = content
    mail.sendTime = os.time()
    mail.gridList = gridList
    mail.title = title
    mail.isRead = 0
    LuaMongo.insert(DB.db_mail, mail)

    mailID2Uid[0] = mailID2Uid[0] + 1
    mailID2Uid[mailID2Uid[0]] = mail._id
    mailUid2ID[mail._id] = mailID2Uid[0]
    mail.mailID = mailID2Uid[0]

    --	print("mail.mailID", mail.mailID)
    --Util.printTable(mailID2Uid)
    --Util.printTable(mailUid2ID)
    return mail
end

function addSystemMessage(recUuid, title, content, gridList)
    local tarHuman = Human.onlineUuid[recUuid]
    if not tarHuman then
        db = RoleDBLogic.getDb(recUuid, "name")
        if not db then
            assert()
        end
    end
    if not Config.IS_MIDDLE then     
        AddMailToUser(recUuid, content, gridList, title)
        if tarHuman and tarHuman.fd then
          local gcRet = Msg.gc.GC_HAS_NEW_MAIL
          gcRet.nouse = 0
          Msg.send(gcRet, tarHuman.fd)
        end
    else
        MiddleLogic.sendMail(recUuid, title, content, gridList)
    end
    return true
end


function DelMail(mail)
    QueryRemoveTable._id = mail._id
    LuaMongo.remove(DB.db_mail, QueryRemoveTable)
end

function MailAttachMentUpdate(human, mailID)
    local mail = GetMailByID(human, mailID)
    if mail == nil then
        return false
    end
    mail.isRead = 1				-- 领取东西后，设为已读
    mail.gridList = nil
    QueryUpdateTable._id = mail._id
    LuaMongo.update(DB.db_mail, QueryUpdateTable, {["$set"]={isRead=mail.isRead}, ["$unset"]={gridList=1}})
    return true
end

--function FetchMailAttachment(human, mail)
--    if mail.gridList ~= nil then
--        for k, v in pairs(mail.gridList) do
--            if v.cnt > 0 and  ItemDefine.isValidId(v.id) then
--                BagLogic.addItemByGrid(human, nil, v, "mail")
--            end
--        end
--        mail.isRead = 1				-- 领取东西后，设为已读
--        mail.gridList = nil
--        QueryUpdateTable._id = mail._id
--        LuaMongo.update(DB.db_mail, QueryUpdateTable, {["$set"]={isRead=mail.isRead}, ["$unset"]={gridList=1}})
--        return true
--    end
--    return false
--end

function GetMailByID(human, mailID)
    local mailUid = mailID and mailID2Uid[mailID]
    if not mailUid then
        return nil
    end
    LuaMongo.find(DB.db_mail, {_id=mailUid})
    local mail = {}
    if not LuaMongo.next(mail) then
        return nil
    end
    mail.mailID = mailID
    return mail
end

function GetMailsCnt(uuid)
    LuaMongo.find(DB.db_mail, {receiverUuid = uuid})
    local cnt = 0
    while true do
        if not LuaMongo.next(mail) then
            break
        end
        cnt = cnt + 1
    end
    return cnt
end

local DBQuery = {receiverUuid=nil}
local DelMailList = {}
function GetMails(human)
    DBQuery.receiverUuid = RoleFFI.ffi_string(human.db._id)

    LuaMongo.find(DB.db_mail, {["$query"] = DBQuery, ["$orderby"] = {sendTime=-1}}, nil, MailDefine.MAX_RECEIVE_MAIL_NUM)
    local data = {}
    data[0] = 0
    local now = os.time()
    while true do
        local mail = {}
        if not LuaMongo.next(mail) then
            break
        end
        local mailID = mailUid2ID[mail._id]
        if not mailID then
            break
        end

        --local del = {}
        if now - mail.sendTime > MailDefine.DEL_MAIL_TIME then
            table.insert(DelMailList, mail)
            --del._id = mailID
            --LuaMongo.remove(DB.db_mail, del)
        else
            data[0] = data[0] + 1
            mail.mailID = mailID
            data[data[0]] = mail
        end
    end

    if #DelMailList > 0 then
        for k,v in ipairs(DelMailList) do
            DelMail(v)
        end
    end
    return data
end

function SetMailRead(human, mail)
    if mail.isRead ~= 1 then
        mail.isRead = 1
        QueryUpdateTable._id = mail._id
        return LuaMongo.update(DB.db_mail, QueryUpdateTable,  {["$set"]={isRead=mail.isRead}})
    end
    return false
end

function OnAttachMentResult(human, oType, msg)
    if msg.result == 0 then
        if MailAttachMentUpdate(human, msg.mailid) then
            local gcRet = Msg.gc.GC_FETCH_ATTACHMENT
            gcRet.mailIDList[0] = 1
            gcRet.mailIDList[1] = msg.mailid
            Msg.send(gcRet, human.fd)
        end
    else
        local msgErr = Msg.gc.GC_BROADCAST
        msgErr.type = Lang.CHAT	+ Lang.MOUSE
        if msg.result == -2 then
            msgErr.msg = Lang.MAIL_BAG_CAP_NOT_ENOUGH
        elseif msg.result == -1 then
            msgErr.msg = Lang.COMMON_ADD_YINLIANG_LIMIT
        end
        Msg.send(msgErr, human.fd)
    end
end
-- 发送好友留言
function sendUserMail(human)
    local mails = GetMails(human, MailDefine.MAIL_TYPE_USER)
    for i = mails[0], 1, -1 do
        local mail = mails[i]
        local gcRet = Msg.gc.GC_SEND_MAIL
        makeMail(gcRet.mail, mail, human.db.name)
        Msg.send(gcRet, human.fd)
    end
end

-- 发送玩家是否有新邮件
function sendHasNewMail(human)
    local mails = GetMails(human, MailDefine.MAIL_TYPE_SYSTEM)
    for i = 1, mails[0] do
        local mail = mails[i]
        if mail and mail.isRead == 0 then
            local gcMsg = Msg.gc.GC_HAS_NEW_MAIL
            gcMsg.nouse = 1
            Msg.send(gcMsg, human.fd)
            return
        end
    end
end


initMailID()
InnerDataManagerFW.Register(InnerDataDefine.INNERDATA_TYPE_MAIL, OnAttachMentResult)
